/**
 * Copyright 2007-2010 非也
 * All rights reserved. 
 * 
 * This library is free software; you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License v3 as published by the Free Software
 * Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along
 * with this library; if not, see http://www.gnu.org/licenses/lgpl.html.
 *
 */
package org.fireflow2.designer.eclipse.commands.service.java;

import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.internal.core.BinaryType;
import org.eclipse.jdt.internal.core.SourceType;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.fireflow.model.binding.ServiceBinding;
import org.fireflow2.designer.eclipse.Activator;
import org.fireflow2.designer.eclipse.commands.service.AbstractServiceCreationWizard;
import org.fireflow2.designer.eclipse.util.Util4Eclipse;

/**
 * 
 * @author 非也 nychen2000@163.com Fire Workflow 官方网站：www.firesoa.com 或者
 *         www.fireflow.org
 * 
 */
public class ConfigOperationBindingPage extends WizardPage {
	private static final String TITLE = "Java调用配置";
	private static final String MESSAGE = "请选择被调用的方法。";

	private static Image methodImage = null;
	private static Image classImage = null;
	IType selectedClassType = null;
	TreeViewer methodListViewer = null;

	Text methodNameText = null;
	IMethod selectedMethod = null;
	
	ServiceBinding serviceBinding = null;

	public IMethod getSelectedMethod(){
		return selectedMethod;
	}
	/**
	 * @param pageName
	 */
	protected ConfigOperationBindingPage(String pageName) {
		super(pageName);
		ImageDescriptor imageDescriptor = ImageDescriptor.createFromFile(Activator.class, "resources/method.png");
		methodImage = imageDescriptor.createImage();
		imageDescriptor = ImageDescriptor.createFromFile(Activator.class, "resources/class.png");
		classImage = imageDescriptor.createImage();
		
		this.setTitle(TITLE);
		this.setMessage(MESSAGE);
		this.setPageComplete(false);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets
	 * .Composite)
	 */
	public void createControl(Composite parent) {
		FormToolkit formToolkit = new FormToolkit(Display.getCurrent());

		Composite composite = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout(2, false);
		composite.setLayout(layout);

		Label lb = new Label(composite, SWT.NULL);
		lb.setText("被选方法：");

		GridData gridData = new GridData(GridData.FILL_HORIZONTAL|GridData.FILL_VERTICAL);
		methodListViewer = new TreeViewer(composite, SWT.SINGLE|SWT.BORDER|SWT.H_SCROLL|SWT.V_SCROLL);
		
		methodListViewer.getControl().setLayoutData(gridData);
		methodListViewer.setLabelProvider(new LabelProvider() {
			public Image getImage(Object element) {
				if (element instanceof ClassTypeWrapper){
					return classImage;
				}
				return methodImage;
			}

			public String getText(Object element) {
				if (element instanceof ClassTypeWrapper){
					return ((ClassTypeWrapper)element).getIType().getFullyQualifiedName();
				}
				IMethod method = (IMethod) element;

				return Util4Eclipse.methodToString(method);
			}

		});
		methodListViewer.setContentProvider(new ITypeTreeContentProvider());
		methodListViewer.addDoubleClickListener(new IDoubleClickListener(){

			public void doubleClick(DoubleClickEvent event) {
				ISelection selection = event.getSelection();
				if (selection instanceof TreeSelection){
					TreeSelection treeSelection = (TreeSelection) selection;
					Object obj = treeSelection.getFirstElement();
					if (obj instanceof IMethod){
						selectedMethod = (IMethod)obj;
						methodNameText.setText(Util4Eclipse.methodToString(selectedMethod));
						setPageComplete(true);
						serviceBinding.setOperationName(selectedMethod.getElementName());
					}
				}
				
			}
			
		});
		
		
		lb = new Label(composite, SWT.NULL);
		lb.setText("已选方法：");

		methodNameText = formToolkit.createText(composite, "");
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		methodNameText.setLayoutData(gridData);
		methodNameText.setEditable(false);
		
		this.setControl(composite);
	}

	public void setVisible(boolean visible) {
		// 刷新Methods
		ConfigJavaServicePage prePage = (ConfigJavaServicePage) this
				.getPreviousPage();
		IType iType = prePage.getIType();
		if (iType != null && !iType.equals(selectedClassType)) {
			selectedClassType = iType;
			methodListViewer.setInput(selectedClassType);
			methodListViewer.expandAll();
		} else if (iType==null){
			selectedClassType = null;
			methodListViewer.setInput(selectedClassType);
			methodListViewer.expandAll();
		}
		
		super.setVisible(visible);
	}
    public void setWizard(IWizard newWizard) {
    	super.setWizard(newWizard);
    	serviceBinding=((AbstractServiceCreationWizard)newWizard).getServiceBinding();
    }

	
	class ITypeTreeContentProvider implements ITreeContentProvider {
		private ClassTypeWrapper input = null;

		/* (non-Javadoc)
		 * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
		 */
		public Object[] getChildren(Object parentElement) {
			if (parentElement instanceof ClassTypeWrapper){
				return Util4Eclipse.findAllPublicMethodsFromIType(((ClassTypeWrapper)parentElement).getIType()).toArray();
			}
			return null;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
		 */
		public Object getParent(Object element) {
			if (element instanceof ClassTypeWrapper){
				return null;
			}else if (element instanceof IMethod){
				return input;
			}
			return null;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
		 */
		public boolean hasChildren(Object element) {
			if (element instanceof ClassTypeWrapper){
				return true;
			}
			
			return false;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
		 */
		public void dispose() {
			// TODO Auto-generated method stub
			
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
		 */
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
			input = new ClassTypeWrapper((IType)newInput);
			
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jface.viewers.ITreeContentProvider#getElements(java.lang.Object)
		 */
		public Object[] getElements(Object inputElement) {
			if (inputElement instanceof SourceType || inputElement instanceof BinaryType){
				return new Object[]{input};
			}else if (inputElement instanceof ClassTypeWrapper){
				this.getChildren(((ClassTypeWrapper)inputElement).getIType());
				
			}
			return new Object[0];
		}
		 
	}
	class ClassTypeWrapper{
		IType iType = null;
		public ClassTypeWrapper(IType type){
			iType = type;
		}
		public IType getIType(){
			return iType;
		}
	}
}
